package com.edu.ctgu;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;

public class DataGenerate {
	// 常量定义
	private static final String DEST_DIR = "src/test/resources/";
	private static final String OUTPUT_FILE = "等价类测试用例.csv";
	private static final String ENCODING = "utf-8";

	// 症状类型索引常量
	private static final int SYMPTOM_COLLECTION = 0;
	private static final int FEVER = 1;
	private static final int COUGH = 2;
	private static final int CHEST_TIGHTNESS = 3;
	private static final int SHORTNESS_OF_BREATH = 4;
	private static final int DIARRHEA = 5;
	private static final int DISCOMFORT = 6;
	private static final int CONTACT_HISTORY = 7;

	// 期望结果常量
	private static final int EXPECTED_NO_SYMPTOMS = 3;
	private static final int EXPECTED_ONLY_CONTACT = 2;
	private static final int EXPECTED_SYMPTOMS_NO_CONTACT = 1;
	private static final int EXPECTED_SYMPTOMS_WITH_CONTACT = 0;

	public static void main(String[] args) throws Exception {
		generateEquivalenceClassTestCases();
	}

	public static void generateEquivalenceClassTestCases() throws Exception {
		try (FileOutputStream fos = new FileOutputStream(DEST_DIR + OUTPUT_FILE);
			 OutputStreamWriter osw = new OutputStreamWriter(fos, ENCODING);
			 CSVPrinter csvPrinter = new CSVPrinter(osw, createCsvFormat())) {

			// 初始化测试数据模型
			int[][] testData = initializeTestData();

			// 生成测试用例
			int testCaseNum = 1;

			// 1. 基础场景测试
			testCaseNum = generateBasicTestCases(csvPrinter, testData, testCaseNum);

			// 2. 发烧相关测试
			testCaseNum = generateFeverTestCases(csvPrinter, testData, testCaseNum);

			// 3. 其他症状测试
			testCaseNum = generateOtherSymptomTestCases(csvPrinter, testData, testCaseNum);

			// 4. 其他疾病测试
			generateOtherDiseaseTestCases(csvPrinter, testData, testCaseNum);
		}
	}

	private static CSVFormat createCsvFormat() {
		return CSVFormat.DEFAULT.withHeader(
				"用例编号",
				"症状采集[0]", "症状采集[1]", "症状采集[2]", "症状采集[3]", "症状采集[4]",
				"症状采集[5]", "症状采集[6]", "症状采集[7]", "症状采集[8]", "症状采集[9]", "症状采集[10]",
				"发烧[0]", "发烧[1](体温)", "发烧[2]", "发烧[3]", "发烧[4]",
				"咳痰", "胸闷", "气急", "腹泻", "本次不舒服",
				"接触史[0]", "接触史[1]", "接触史[2]", "接触史[3]",
				"期望值"
		);
	}

	private static int[][] initializeTestData() {
		return new int[][] {
				{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 症状采集
				{ -1, -1, -1, -1, -1 },                         // 发烧相关
				{ -1 },                                         // 咳痰
				{ -1 },                                         // 胸闷
				{ -1 },                                         // 气急
				{ -1 },                                         // 腹泻
				{ -1 },                                         // 本次不舒服
				{ -1, -1, -1, -1 }                              // 接触史
		};
	}

	private static int generateBasicTestCases(CSVPrinter csvPrinter, int[][] testData, int testCaseNum) throws Exception {
		// 检测全为0
		testData[SYMPTOM_COLLECTION][0] = 0;
		testData[CONTACT_HISTORY][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_NO_SYMPTOMS);

		// 检测仅有接触史等
		for (int i = 1; i < 5; i++) {
			testData[CONTACT_HISTORY][0] = i;
			printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_ONLY_CONTACT);
		}

		// 检测所有接触史类型
		testData[CONTACT_HISTORY][0] = 1;
		testData[CONTACT_HISTORY][1] = 2;
		testData[CONTACT_HISTORY][2] = 3;
		testData[CONTACT_HISTORY][3] = 4;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_ONLY_CONTACT);

		// 重置接触史
		resetContactHistory(testData);
		return testCaseNum;
	}

	private static int generateFeverTestCases(CSVPrinter csvPrinter, int[][] testData, int testCaseNum) throws Exception {
		testData[DISCOMFORT][0] = 0;
		testData[CONTACT_HISTORY][0] = 0;
		testData[SYMPTOM_COLLECTION][0] = 1;

		// 发烧测试组合1
		testData[FEVER][0] = 0;  // 发烧状态1
		testData[FEVER][1] = 373; // 体温
		testData[FEVER][2] = 0;   // 发烧状态2
		testData[FEVER][3] = 0;   // 发烧状态3
		testData[FEVER][4] = 0;   // 发烧状态4
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 发烧测试组合2
		testData[FEVER][0] = 1;
		testData[FEVER][2] = 1;
		testData[FEVER][3] = 1;
		testData[FEVER][4] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 发烧测试组合3
		testData[FEVER][2] = 2;
		testData[FEVER][4] = 2;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 重置发烧数据
		resetFeverData(testData);
		return testCaseNum;
	}

	private static int generateOtherSymptomTestCases(CSVPrinter csvPrinter, int[][] testData, int testCaseNum) throws Exception {
		// 咳嗽测试
		testData[SYMPTOM_COLLECTION][0] = 3;
		testData[COUGH][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		testData[COUGH][0] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 胸闷测试
		testData[COUGH][0] = -1;
		testData[SYMPTOM_COLLECTION][0] = 6;
		testData[CHEST_TIGHTNESS][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		testData[CHEST_TIGHTNESS][0] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 气急测试
		testData[CHEST_TIGHTNESS][0] = -1;
		testData[SYMPTOM_COLLECTION][0] = 7;
		testData[SHORTNESS_OF_BREATH][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		testData[SHORTNESS_OF_BREATH][0] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 腹泻测试
		testData[SHORTNESS_OF_BREATH][0] = -1;
		testData[SYMPTOM_COLLECTION][0] = 11;
		testData[DIARRHEA][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		testData[DIARRHEA][0] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		return testCaseNum;
	}

	private static void generateOtherDiseaseTestCases(CSVPrinter csvPrinter, int[][] testData, int testCaseNum) throws Exception {
		// 重置数据
		testData[DIARRHEA][0] = -1;
		testData[SYMPTOM_COLLECTION][0] = 9;
		testData[DISCOMFORT][0] = 1;

		// 其他疾病测试1
		testData[CONTACT_HISTORY][0] = 0;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_NO_CONTACT);

		// 其他疾病测试2
		testData[CONTACT_HISTORY][0] = 1;
		printTestCase(csvPrinter, testData, testCaseNum++, EXPECTED_SYMPTOMS_WITH_CONTACT);
	}

	private static void printTestCase(CSVPrinter csvPrinter, int[][] testData, int testCaseNum, int expectedValue) throws Exception {
		csvPrinter.printRecord(
				testCaseNum,
				testData[SYMPTOM_COLLECTION][0], testData[SYMPTOM_COLLECTION][1], testData[SYMPTOM_COLLECTION][2],
				testData[SYMPTOM_COLLECTION][3], testData[SYMPTOM_COLLECTION][4], testData[SYMPTOM_COLLECTION][5],
				testData[SYMPTOM_COLLECTION][6], testData[SYMPTOM_COLLECTION][7], testData[SYMPTOM_COLLECTION][8],
				testData[SYMPTOM_COLLECTION][9], testData[SYMPTOM_COLLECTION][10],
				testData[FEVER][0], testData[FEVER][1], testData[FEVER][2], testData[FEVER][3], testData[FEVER][4],
				testData[COUGH][0],
				testData[CHEST_TIGHTNESS][0],
				testData[SHORTNESS_OF_BREATH][0],
				testData[DIARRHEA][0],
				testData[DISCOMFORT][0],
				testData[CONTACT_HISTORY][0], testData[CONTACT_HISTORY][1], testData[CONTACT_HISTORY][2], testData[CONTACT_HISTORY][3],
				expectedValue
		);
	}

	private static void resetContactHistory(int[][] testData) {
		for (int i = 0; i < testData[CONTACT_HISTORY].length; i++) {
			testData[CONTACT_HISTORY][i] = -1;
		}
	}

	private static void resetFeverData(int[][] testData) {
		for (int i = 0; i < testData[FEVER].length; i++) {
			testData[FEVER][i] = -1;
		}
	}
}